<?php

namespace App\Http\Controllers;

use App\Http\Model\Hint;
use App\Http\Model\OutJson;
use App\Http\Model\User;
use App\Http\Services\UserServices;
use App\Lib\PvLog;
use App\Lib\Response;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

class BaseController extends Controller
{
    // TODO 默认全局参数【勿动】
    public $requestData = [];// 请求参数
    public $responseData = []; // 返回响应数据
    public $userInfo = [];// 用户信息

    /**
     * 初始化实例
     * */
    public function initInstance()
    {
        // 自定义header请在此处定义，之前不可有任何输出，否则无效

        // header("content-type:application/json;chartset=uft-8");
        // 允许所有域名访问
        // header('Access-Control-Allow-Origin:*');
        // 响应所有类型
        // header('Access-Control-Allow-Methods:*');
        // 响应头设置
        // header('Access-Control-Allow-Headers:x-requested-with,content-type,Authorization');

        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        do {
            /**
             * OPTIONS 过滤请求方式
             * */
            if (($_SERVER['REQUEST_METHOD'] ?? '') === 'OPTIONS') {
                header('HTTP/1.1 200 OK');
                $msg = 'OPTIONS';
                break;
            }

            /**
             * 接收请求参数
             * */
            // 获取流数据
            $jsonInput = file_get_contents("php://input");
            json_decode($jsonInput);
            if (json_last_error() == JSON_ERROR_NONE) {
                $jsonInput = json_decode($jsonInput, true);
            } else {
                // XML解析
                $xmlParser = xml_parser_create();
                if (xml_parse($xmlParser, $jsonInput, true)) {
                    $jsonInput = simplexml_load_string($jsonInput, 'SimpleXMLElement', LIBXML_NOCDATA);
                    $jsonInput = json_decode(json_encode($jsonInput), true);
                } else {
                    // 查询字符串解析到变量中
                    parse_str($jsonInput, $jsonInput);
                }

                xml_parser_free($xmlParser);// 释放 XML 解析器
            }

            // 原始参数
            $this->requestData = array_merge($_FILES, $_POST, $_GET, $jsonInput);

            // 过滤数组空值
            /* $this->requestData = array_filter($this->requestData);
            if (empty($this->requestData)) {
                $code = Dao_Common_ErrorModel::ERR_PARAMS_CHECK_FAIL;
                break;
            }*/

        } while (false);

        return compact('code', 'msg', 'data');
    }


    /**
     * 校验请求
     *
     * @param bool needLogin 是否需要登录 true默认需要登录 false不需要登录
     * @return bool
     * */
    public function checkRequest($needLogin = true)
    {
        $code = Hint::SUCCESS;
        $msg = Hint::getErrCodeMsg($code);
        $data = [];

        // 校验是否通过状态 true false
        $checkStatus = false;

        do {

            $restInit = $this->initInstance();
            if ($restInit['code'] !== $code) {
                $code = $restInit['code'];
                $msg = $restInit['msg'];
                break;
            }
            if ($restInit['msg'] === 'OPTIONS') {
                break;
            }

            if ($needLogin) {

                // 校验登录用户信息
                $userService = new UserServices();
                $this->userInfo = $userService->get_current_user();
                $userId = $this->userInfo['user_id'] ?? 0;
                if (is_null($this->userInfo) or empty($this->userInfo) or empty($userId)) {
                    $code = Hint::ERR_USER_LOGIN_STATUS;
                    $msg = Hint::getErrCodeMsg($code);
                    break;
                }

                // 加到请求参数中
                $this->requestData['user_id'] = $userId;
            }

            $checkStatus = true;

        } while (false);

        $result = compact('code', 'msg', 'data');

        // TODO LOG INFO REQUEST CHECK
        /*Log::info('requestCheck', [
            'requestParams' => $this->requestData,
            'requestOutput' => $result,
        ]);*/

        // 数据赋值
        $this->responseData = json_encode($result, JSON_UNESCAPED_UNICODE);

        return $checkStatus;
    }

    /**
     * 调用公用 Model
     * @param ..className  类实例对象
     * @param string method  方法名
     * @param array data 参数
     * @param bool encode 默认需要编码
     * @return mixed
     */
    public function callCommon($className, $method, $data = [], $encode = true)
    {
        // 实例化
        $classInstance = new $className();
        // 构造传值参数 data参数
        $classInstance->requestData = $data;
        // 调用类方法 data参数
        $result = $classInstance->$method($data);

        // TODO LOG INFO REQUEST OUTPUT
        /*Log::info('callCommon_' . $method, [
            'requestOutput' => $result,
        ]);*/

        // 返回响应数据
        if ($encode) {
            $this->responseData = json_encode($result, JSON_UNESCAPED_UNICODE);
        } else {
            $this->responseData = $result;
        }

        return $this->responseData;
    }

    /**
     * 响应输出
     * */
    public function responseData($responseData = [])
    {
        if (empty($this->responseData) and !empty($responseData)) {
            $this->responseData = $responseData;
        }

        // http api version = 1
        $httpApiVersion = $_SERVER['HTTP_API_VERSION'] ?? 0;

        if (is_string($this->responseData) and $httpApiVersion == 1) $this->responseData = json_decode($this->responseData, true);

        if (is_array($this->responseData)) {

            // TODO 兼容问题 data为空则干掉
            if ($httpApiVersion == 1 and isset($this->responseData['data']) and empty($this->responseData['data'])) unset($this->responseData['data']);

            $this->responseData = json_encode($this->responseData, JSON_UNESCAPED_UNICODE);
        }
        //$this->_pvLog($this->responseData); by wj
        echo $this->responseData;
        exit;
    }

    /**
     * 验证参数是否合法
     * @param array $params
     * @param array $rules
     * @param array $messages
     * @return array
     */
    public function validateParams(array $params, array $rules, array $messages): array
    {
        $validator = Validator::make($params, $rules, $messages);
        if ($validator->fails()) {
            Response::returnResult(Hint::PARAM_ERROR, [], $validator->errors()->first());
        }

        return $validator->validated();
    }

    /**
     * 获取登录用户id
     *
     * @return int
     */
    public function getLoginUserId(): int
    {
        $userService = new UserServices();
        $userInfo = $userService->get_current_user();
        return $userInfo ? ($userInfo['user_id'] ?? 0) : 0;
    }

    private function _pvLog($response){
        PvLog::$response = $response;
        PvLog::$requestTime = date('Y-m-d H:i:s');
        PvLog::$ip = client_ip();
        $userService = new UserServices();
        if(isset($this->userInfo['user_id'])){
            PvLog::$userId = $this->userInfo['user_id'];
        } else {
            PvLog::$userId = $userService->get_current_user_id()??0;
        }
        PvLog::$cookie = $userService->get_current_user_cookie();
        PvLog::write();
    }

    /**
     * 获取登录用户信息
     */
    public function getLoginUserInfo()
    {
        $userService = new UserServices();
        $userInfo = $userService->get_current_user();
        return empty($userInfo['user_id']) ? [] : $userInfo;
    }

}